<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 5.4.0">
  <link rel="apple-touch-icon" sizes="180x180" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="32x32" href="/images/favicon.ico">
  <link rel="icon" type="image/png" sizes="16x16" href="/images/favicon.ico">
  <link rel="mask-icon" href="/images/favicon.ico" color="#222">

<link rel="stylesheet" href="/css/main.css">


<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">

<script id="hexo-configurations">
    var NexT = window.NexT || {};
    var CONFIG = {"hostname":"yoursite.com","root":"/","scheme":"Mist","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"always","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},"path":"search.xml"};
  </script>

  <meta name="description" content="进程和线程、通信方式、并行和并发、同步和异步、阻塞和非阻塞相关概念笔记笔记">
<meta property="og:type" content="article">
<meta property="og:title" content="进程和线程相关概念">
<meta property="og:url" content="http://yoursite.com/2018/11/17/basic-2018-10-17-ipc-thread/index.html">
<meta property="og:site_name" content="Akiyama&#39;s Blog">
<meta property="og:description" content="进程和线程、通信方式、并行和并发、同步和异步、阻塞和非阻塞相关概念笔记笔记">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="http://yoursite.com/images/Thread/treadstate.png">
<meta property="article:published_time" content="2018-11-16T16:00:00.000Z">
<meta property="article:modified_time" content="2020-05-31T11:30:47.341Z">
<meta property="article:author" content="丘山月夜">
<meta property="article:tag" content="程序基础">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="http://yoursite.com/images/Thread/treadstate.png">

<link rel="canonical" href="http://yoursite.com/2018/11/17/basic-2018-10-17-ipc-thread/">


<script id="page-configurations">
  // https://hexo.io/docs/variables.html
  CONFIG.page = {
    sidebar: "",
    isHome : false,
    isPost : true,
    lang   : 'zh-CN'
  };
</script>

  <title>进程和线程相关概念 | Akiyama's Blog</title>
  






  <noscript>
  <style>
  .use-motion .brand,
  .use-motion .menu-item,
  .sidebar-inner,
  .use-motion .post-block,
  .use-motion .pagination,
  .use-motion .comments,
  .use-motion .post-header,
  .use-motion .post-body,
  .use-motion .collection-header { opacity: initial; }

  .use-motion .site-title,
  .use-motion .site-subtitle {
    opacity: initial;
    top: initial;
  }

  .use-motion .logo-line-before i { left: initial; }
  .use-motion .logo-line-after i { right: initial; }
  </style>
</noscript>

</head>

<body itemscope itemtype="http://schema.org/WebPage">
  <div class="container use-motion">
    <div class="headband"></div>

    <header class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-container">
  <div class="site-nav-toggle">
    <div class="toggle" aria-label="切换导航栏">
      <span class="toggle-line toggle-line-first"></span>
      <span class="toggle-line toggle-line-middle"></span>
      <span class="toggle-line toggle-line-last"></span>
    </div>
  </div>

  <div class="site-meta">

    <a href="/" class="brand" rel="start">
      <span class="logo-line-before"><i></i></span>
      <h1 class="site-title">Akiyama's Blog</h1>
      <span class="logo-line-after"><i></i></span>
    </a>
      <p class="site-subtitle" itemprop="description">丘山月夜的博客</p>
  </div>

  <div class="site-nav-right">
    <div class="toggle popup-trigger">
    </div>
  </div>
</div>




<nav class="site-nav">
  <ul id="menu" class="main-menu menu">
        <li class="menu-item menu-item-home">

    <a href="/" rel="section"><i class="home fa fa-home fa-fw"></i>首页</a>

  </li>
        <li class="menu-item menu-item-about">

    <a href="/about/" rel="section"><i class="user fa fa-user fa-fw"></i>关于</a>

  </li>
        <li class="menu-item menu-item-tags">

    <a href="/tags/" rel="section"><i class="tags fa fa-tags fa-fw"></i>标签</a>

  </li>
        <li class="menu-item menu-item-categories">

    <a href="/categories/" rel="section"><i class="th fa fa-th fa-fw"></i>分类</a>

  </li>
        <li class="menu-item menu-item-archives">

    <a href="/archives/" rel="section"><i class="archive fa fa-archive fa-fw"></i>归档</a>

  </li>
  </ul>
</nav>




</div>
    </header>

    
  <div class="back-to-top">
    <i class="fa fa-arrow-up"></i>
    <span>0%</span>
  </div>


    <main class="main">
      <div class="main-inner">
        <div class="content-wrap">
          

          <div class="content post posts-expand">
            

    
  
  
  <article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
    <link itemprop="mainEntityOfPage" href="http://yoursite.com/2018/11/17/basic-2018-10-17-ipc-thread/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="image" content="/images/avatar.png">
      <meta itemprop="name" content="丘山月夜">
      <meta itemprop="description" content="君は空を見てるか,<br>風の音を聞いてるか">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Akiyama's Blog">
    </span>
      <header class="post-header">
        <h1 class="post-title" itemprop="name headline">
          进程和线程相关概念
        </h1>

        <div class="post-meta">
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-calendar"></i>
              </span>
              <span class="post-meta-item-text">发表于</span>

              <time title="创建时间：2018-11-17 00:00:00" itemprop="dateCreated datePublished" datetime="2018-11-17T00:00:00+08:00">2018-11-17</time>
            </span>
              <span class="post-meta-item">
                <span class="post-meta-item-icon">
                  <i class="far fa-calendar-check"></i>
                </span>
                <span class="post-meta-item-text">更新于</span>
                <time title="修改时间：2020-05-31 19:30:47" itemprop="dateModified" datetime="2020-05-31T19:30:47+08:00">2020-05-31</time>
              </span>
            <span class="post-meta-item">
              <span class="post-meta-item-icon">
                <i class="far fa-folder"></i>
              </span>
              <span class="post-meta-item-text">分类于</span>
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/" itemprop="url" rel="index"><span itemprop="name"></span></a>
                </span>
            </span>

          
            <div class="post-description">进程和线程、通信方式、并行和并发、同步和异步、阻塞和非阻塞相关概念笔记笔记</div>

        </div>
      </header>

    
    
    
    <div class="post-body" itemprop="articleBody">

      
        <h1 id="1-进程和线程"><a href="#1-进程和线程" class="headerlink" title="1. 进程和线程"></a>1. 进程和线程</h1><p>进程：一个具有一定独立功能的程序关于某个数据集合的一次运行活动，是系统进行资源分配和调度运行的基本单位</p>
<ul>
<li>正在运行的一个程序（动态的概念，程序是静态的概念）</li>
<li>每个进程拥有独立的地址空间</li>
<li>同一时刻cpu（单核）只运行一个进程</li>
</ul>
<p>线程：进程的一个实体，进程的一条执行路径，轻量级的进程</p>
<ul>
<li>一个进程可以拥有多个线程</li>
<li>每个线程由独立的栈空间</li>
<li>同一进程的多个线程共享内存区域（而进程无法访问其他进程的内存）</li>
</ul>
<h1 id="2-并行和并发"><a href="#2-并行和并发" class="headerlink" title="2. 并行和并发"></a>2. 并行和并发</h1><ul>
<li>并行是同一时刻做多件事情，并发是同一时间间隔内做多件事情</li>
<li>并行是同时做很多事情。并发是一次处理很多事情。</li>
<li>并行是同时执行（可能相关的）计算（依靠多核处理）。并发可以是虚拟的同时执行也可以是真的同时执行（有空闲的cpu，轮流占用CPU和各种资源）。</li>
</ul>
<h1 id="3-进程间通信方式"><a href="#3-进程间通信方式" class="headerlink" title="3. 进程间通信方式"></a>3. 进程间通信方式</h1><p>进程间通信（IPC，Inter-Process Communication）,指多个进程之间相互通信，交换数据的方法。</p>
<p>进程的互斥（mutual exclusion ）是解决进程间竞争关系( <strong>间接制约关系</strong>) 的手段。 进程互斥指若干个进程要使用同一共享资源时，任何时刻最多允许一个进程去使用，其他要使用该资源的进程必须等待，直到占有资源的进程释放该资源。</p>
<p>进程同步指两个以上进程基于某个条件来协调它们的活动。一个进程的执行依赖于另一个协作进程的消息或信号，当一个进程没有得到来自于另一个进程的消息或信号时则需等待，直到消息或信号到达才被唤醒。</p>
<p>进程同步是一种进程通信。进程互斥是一种特殊的同步</p>
<h2 id="3-1-管道-pipe"><a href="#3-1-管道-pipe" class="headerlink" title="3.1. 管道( pipe )"></a>3.1. 管道( pipe )</h2><p>管道是一种半双工的通信方式，数据只能单向流动，而且只能在具有亲缘关系的进程间使用。进程的亲缘关系通常是指父子进程关系。</p>
<h2 id="3-2-有名管道-namedpipe"><a href="#3-2-有名管道-namedpipe" class="headerlink" title="3.2. 有名管道 (namedpipe)"></a>3.2. 有名管道 (namedpipe)</h2><p>有名管道也是半双工的通信方式，但是它允许无亲缘关系进程间的通信。</p>
<h2 id="3-3-信号量-semophore"><a href="#3-3-信号量-semophore" class="headerlink" title="3.3. 信号量(semophore )"></a>3.3. 信号量(semophore )</h2><p>信号量是一个计数器，可以用来控制多个进程对共享资源的访问。它常作为一种锁机制，防止某进程正在访问共享资源时，其他进程也访问该资源。因此，主要作为进程间以及同一进程内不同线程之间的同步手段。</p>
<p><strong>补充</strong></p>
<p>互斥锁（mutex）：是一种特殊的信号量，当n=1时。防止多个线程同时读写某一块内存区域</p>
<h2 id="3-4-消息队列-messagequeue"><a href="#3-4-消息队列-messagequeue" class="headerlink" title="3.4. 消息队列( messagequeue )"></a>3.4. 消息队列( messagequeue )</h2><p> 消息队列是由消息的链表，存放在内核中并由消息队列标识符标识。消息队列克服了信号传递信息少、管道只能承载无格式字节流以及缓冲区大小受限等缺点。</p>
<h2 id="3-5-信号-sinal"><a href="#3-5-信号-sinal" class="headerlink" title="3.5. 信号 (sinal )"></a>3.5. 信号 (sinal )</h2><p> 信号是一种比较复杂的通信方式，用于通知接收进程某个事件已经发生。</p>
<h2 id="3-6-共享内存-shared-memory"><a href="#3-6-共享内存-shared-memory" class="headerlink" title="3.6. 共享内存(shared memory )"></a>3.6. 共享内存(shared memory )</h2><p>共享内存就是映射一段能被其他进程所访问的内存，这段共享内存由一个进程创建，但多个进程都可以访问。共享内存是最快的 IPC 方式，它是针对其他进程间通信方式运行效率低而专门设计的。它往往与其他通信机制，如信号两，配合使用，来实现进程间的同步和通信。</p>
<h2 id="3-7-套接字-socket"><a href="#3-7-套接字-socket" class="headerlink" title="3.7. 套接字(socket )"></a>3.7. 套接字(socket )</h2><p>套接口也是一种进程间通信机制，与其他通信机制不同的是，它可用于不同机器间的进程通信。</p>
<h1 id="4-线程间的同步"><a href="#4-线程间的同步" class="headerlink" title="4. 线程间的同步"></a>4. 线程间的同步</h1><p>各个线程可以访问同一进程中的公共变量，资源，所以使用多线程的过程中需要注意的问题是如何防止两个或两个以上的线程同时访问同一个数据，以免破坏数据的完整性。数据之间的相互制约包括<br>1、直接制约关系，即一个线程的处理结果，为另一个线程的输入，因此线程之间直接制约着，这种关系可以称之为同步关系<br>2、间接制约关系，即两个线程需要访问同一资源，该资源在同一时刻只能被一个线程访问，这种关系称之为线程间对资源的互斥访问，某种意义上说互斥是一种制约关系更小的同步</p>
<h2 id="4-1-锁机制：包括互斥锁、读写锁、条件变量"><a href="#4-1-锁机制：包括互斥锁、读写锁、条件变量" class="headerlink" title="4.1. 锁机制：包括互斥锁、读写锁、条件变量"></a>4.1. 锁机制：包括互斥锁、读写锁、条件变量</h2><ul>
<li>互斥锁提供了以排他方式防止数据结构被并发修改的方法。</li>
<li>读写锁允许多个线程同时读共享数据，而对写操作是互斥的。</li>
<li>条件变量可以以原子的方式阻塞进程，直到某个特定条件为真为止。对条件的测试是在互斥锁的保护下进行的。条件变量始终与互斥锁一起使用。</li>
</ul>
<h2 id="4-2-信号量机制-Semaphore-：包括无名线程信号量和命名线程信号量"><a href="#4-2-信号量机制-Semaphore-：包括无名线程信号量和命名线程信号量" class="headerlink" title="4.2. 信号量机制(Semaphore)：包括无名线程信号量和命名线程信号量"></a>4.2. 信号量机制(Semaphore)：包括无名线程信号量和命名线程信号量</h2><p>允许多个线程使用共享资源，规定访问共享资源线程的最大数目</p>
<h2 id="4-3-信号机制-Signal-：类似进程间的信号处理"><a href="#4-3-信号机制-Signal-：类似进程间的信号处理" class="headerlink" title="4.3. 信号机制(Signal)：类似进程间的信号处理"></a>4.3. 信号机制(Signal)：类似进程间的信号处理</h2><h2 id="4-4-临界区"><a href="#4-4-临界区" class="headerlink" title="4.4. 临界区"></a>4.4. 临界区</h2><p>通过对多线程的串行化来访问公共资源或一段代码，速度快，适合控制数据访问。</p>
<h1 id="5-java线程间的通信方式"><a href="#5-java线程间的通信方式" class="headerlink" title="5. java线程间的通信方式"></a>5. java线程间的通信方式</h1><h2 id="5-1-使用共享对象"><a href="#5-1-使用共享对象" class="headerlink" title="5.1. 使用共享对象"></a>5.1. 使用共享对象</h2><p>同一进程中所有线程共享内存区域，因此定义全局变量可供其他线程访问。多线程访问全局变量时最好声明为volatile</p>
<p>volatile能够保证可见性，不能保证原子性，正常情况下内存会拷贝到cpu缓存中，当多个线程运行在不同cpu上的时候对一个变量修改会导致不同步，使用volatile声明之后会直接从内存中读取，不会进行cpu缓存。</p>
<p>synchronized同步能够保证可见性和原子性，同一时刻只允许一个线程访问资源。</p>
<p>synchronized修饰：实例方法、静态方法、代码块</p>
<p>synchronized可以同步方法和同步代码块</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//同步代码块，持有this对象的锁</span></span><br><span class="line"><span class="keyword">synchronized</span>(<span class="keyword">this</span>)&#123;</span><br><span class="line">    <span class="comment">//doSomething……</span></span><br><span class="line">&#125;</span><br><span class="line"><span class="comment">//同步方法，默认传入this</span></span><br><span class="line"> <span class="function"><span class="keyword">public</span> <span class="keyword">synchronized</span> <span class="keyword">void</span> <span class="title">func</span><span class="params">()</span> </span>&#123;</span><br><span class="line"> &#125;</span><br></pre></td></tr></table></figure>

<p><strong>synchronized实际上锁住的是对象，而不是代码块</strong></p>
<p>新建一个实例其他线程仍然可以执行代码块。要想锁住代码块，可以使用下面的方式</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//持有class对象的锁</span></span><br><span class="line"><span class="keyword">synchronized</span>(Test.class)&#123;</span><br><span class="line">    <span class="comment">//doSomething……</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="区别"><a href="#区别" class="headerlink" title="区别"></a>区别</h3><ol>
<li>volatile本质是在告诉jvm当前变量在寄存器（工作内存）中的值是不确定的，需要从主存中读取； synchronized则是锁定当前变量，只有当前线程可以访问该变量，其他线程被阻塞住。</li>
<li>volatile仅能实现变量的修改可见性，不能保证原子性；而synchronized则可以保证变量的修改可见性和原子性</li>
<li>volatile不会造成线程的阻塞；synchronized可能会造成线程的阻塞。</li>
<li>volatile仅能使用在变量级别；synchronized则可以使用在变量、方法、和类级别的</li>
</ol>
<h2 id="5-2-while轮询：忙等状态，消耗cpu资源。可使用wait阻塞替代"><a href="#5-2-while轮询：忙等状态，消耗cpu资源。可使用wait阻塞替代" class="headerlink" title="5.2. while轮询：忙等状态，消耗cpu资源。可使用wait阻塞替代"></a>5.2. while轮询：忙等状态，消耗cpu资源。可使用wait阻塞替代</h2><h2 id="5-3-接口回调"><a href="#5-3-接口回调" class="headerlink" title="5.3. 接口回调"></a>5.3. 接口回调</h2><h3 id="java提供的Callable，Future，ExecutorService。"><a href="#java提供的Callable，Future，ExecutorService。" class="headerlink" title="java提供的Callable，Future，ExecutorService。"></a>java提供的Callable，Future，ExecutorService。</h3><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//ExecutorService提供的方法，传入Callable，submit会封装成FutureTask（继承RunnableFuture接口）然后执行</span></span><br><span class="line">&lt;T&gt; <span class="function">Future&lt;T&gt; <span class="title">submit</span><span class="params">(Callable&lt;T&gt; task)</span></span>;</span><br></pre></td></tr></table></figure>

<p>Future的get()方法用来获取执行结果，会阻塞线程，直到任务执行完毕。</p>
<h2 id="5-4-IO管道流：PipedInputStream，PipedOutputStream"><a href="#5-4-IO管道流：PipedInputStream，PipedOutputStream" class="headerlink" title="5.4. IO管道流：PipedInputStream，PipedOutputStream"></a>5.4. IO管道流：PipedInputStream，PipedOutputStream</h2><h2 id="5-5-socket套接字"><a href="#5-5-socket套接字" class="headerlink" title="5.5. socket套接字"></a>5.5. socket套接字</h2><h2 id="5-6-消息队列"><a href="#5-6-消息队列" class="headerlink" title="5.6. 消息队列"></a>5.6. 消息队列</h2><h2 id="5-7-wait-，notify-，notifyAll-阻塞和唤醒线程"><a href="#5-7-wait-，notify-，notifyAll-阻塞和唤醒线程" class="headerlink" title="5.7. wait()，notify()，notifyAll()阻塞和唤醒线程"></a>5.7. wait()，notify()，notifyAll()阻塞和唤醒线程</h2><p> 这三个方法都是属于Object的本地final方法；无法被重写，所有类都可以调用这三方法； </p>
<ul>
<li><p>wait()：使当前线程等待，并且释放锁，直到其他线程调用notify()或者notifyAll()方法唤醒。</p>
</li>
<li><p>notify()：唤醒一个等待当前对象的锁的线程（随机）。</p>
</li>
<li><p>notifyAll(）就是唤醒所有在等待当前对象的线程。</p>
</li>
</ul>
<p>wait()和notify()方法要求在调用时线程持有对象的锁，因为线程只有在同步块中才会占用对象的锁，因此对这两个方法的调用需要放在synchronized方法或synchronized块中。</p>
<p>不持有锁的话可能会产生竞态问题，notify可能比wait先执行，导致一直wait</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//使用synchronized获取对象锁，在同步块中使用wait方法让当前线程进入等待状态，等待当前锁住的对象，</span></span><br><span class="line"><span class="comment">//同样的在另一个同步块中使用notify方法释放对象锁，唤醒等待该对象锁的线程。</span></span><br><span class="line"><span class="keyword">synchronized</span>(obj)&#123;</span><br><span class="line">	obj.wait();</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">synchronized</span>(obj)&#123;</span><br><span class="line">	obj.notify();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>锁池和等待池</strong></p>
<p>锁池：线程A持有某个对象的锁，导致其他线程不能访问该对象的synchronized方法（代码块），这些线程就会进入锁池，等待对象的锁被释放，与其他线程竞争锁</p>
<p>等待池：线程A调用了某个对象的wait方法，线程A就会释放该对象的锁，进入到该对象的等待池。不会去竞争锁</p>
<p>notify会将等待池中的线程唤醒，被唤醒的线程从等待池进入锁池，与其他线程竞争锁</p>
<p><strong>synchronized是非公平锁，线程需要竞争锁</strong></p>
<p><strong>公平锁：可以使用FIFO（先进先出），维护一个队列，让先进的线程获得锁</strong></p>
<h1 id="6-线程状态"><a href="#6-线程状态" class="headerlink" title="6. 线程状态"></a>6. 线程状态</h1><p><strong><a target="_blank" rel="noopener" href="https://www.cnblogs.com/happy-coder/p/6587092.html">转自此处</a></strong></p>
<p><img src="/images/Thread/treadstate.png" alt="线程状态"></p>
<h2 id="6-1-线程共包括以下5种状态。"><a href="#6-1-线程共包括以下5种状态。" class="headerlink" title="6.1. 线程共包括以下5种状态。"></a>6.1. 线程共包括以下5种状态。</h2><ol>
<li>新建状态(New)         : 线程对象被创建后，就进入了新建状态。例如，Thread thread = new Thread()。</li>
<li>就绪状态(Runnable): 也被称为“可执行状态”。线程对象被创建后，其它线程调用了该对象的start()方法，从而来启动该线程。例如，thread.start()。处于就绪状态的线程，随时可能被CPU调度执行。</li>
<li>运行状态(Running) : 线程获取CPU权限进行执行。需要注意的是，线程只能从就绪状态进入到运行状态。</li>
<li>阻塞状态(Blocked)  : 阻塞状态是线程因为某种原因放弃CPU使用权，暂时停止运行。直到线程进入就绪状态，才有机会转到运行状态。阻塞的情况分三种：<ul>
<li>等待阻塞 – 通过调用线程的wait()方法，让线程等待某工作的完成。</li>
<li> 同步阻塞 – 线程在获取synchronized同步锁失败(因为锁被其它线程所占用)，它会进入同步阻塞状态。</li>
<li> 其他阻塞 – 通过调用线程的sleep()或join()或发出了I/O请求时，线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时，线程重新转入就绪状态。</li>
</ul>
</li>
<li>死亡状态(Dead)    : 线程执行完了或者因异常退出了run()方法，该线程结束生命周期。</li>
</ol>
<h2 id="6-2-yield，sleep，join都是Thread的方法"><a href="#6-2-yield，sleep，join都是Thread的方法" class="headerlink" title="6.2. yield，sleep，join都是Thread的方法"></a>6.2. yield，sleep，join都是Thread的方法</h2><p>yield：让步，让当前线程由运行状态进入到就绪状态，从而让其他线程有机会获得cpu（一般是更高优先级的线程，也可能当前线程立马获得cpu）</p>
<p>sleep: 让线程休眠一段时间，进入阻塞状态。放弃cpu，给其他线程执行的机会，但是不释放对象锁，如果加了锁，其他线程还是不能使用资源</p>
<p>join：当前线程挂起，让指定的另一个线程执行。join（long）方法在内部使用的是 wait (long) 方法来实现的；所以join（long）方法具有释放锁的特点。（相当于在程序中间插入了一段代码）</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">Main</span></span>&#123;</span><br><span class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">static</span> <span class="keyword">void</span> <span class="title">main</span><span class="params">(String[] args)</span></span>&#123;</span><br><span class="line">        Thread t = <span class="keyword">new</span> Thread();</span><br><span class="line">        <span class="comment">//主线程会阻塞，直到t线程执行完毕。</span></span><br><span class="line">        <span class="comment">//join的意思是加入，即将线程排队，把t线程加入到队伍里面去</span></span><br><span class="line">        <span class="comment">//也可以传入时间参数，表示主线程只等待一段时间</span></span><br><span class="line">        t.join();</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>sleep是native方法，并且是静态的，一般使用<code>Thread.sleep(1000);</code>让当前线程休眠</p>
<h1 id="7-同步和异步、阻塞与非阻塞"><a href="#7-同步和异步、阻塞与非阻塞" class="headerlink" title="7. 同步和异步、阻塞与非阻塞"></a>7. 同步和异步、阻塞与非阻塞</h1><p>“阻塞”与”非阻塞”与”同步”与“异步”不能简单的从字面理解，提供一个从分布式系统角度的回答。</p>
<h2 id="7-1-同步与异步"><a href="#7-1-同步与异步" class="headerlink" title="7.1. 同步与异步"></a>7.1. 同步与异步</h2><p>同步和异步关注的是消息通信机制 (synchronous communication/ asynchronous communication)<br>同步：就是在发出一个调用时，在没有得到结果之前，该调用就不返回。但是一旦调用返回，就得到返回值了。<br>换句话说，就是由调用者主动等待这个调用的结果。</p>
<p>异步：调用在发出之后，方法立即返回，但是结果还没返回。等待计算完结果后被调用者通过状态、消息通知来通知调用者，或通过回调函数处理这个调用。</p>
<p>注：这里的同步和java的线程同步不一样，线程同步是为了防止多个线程修改共有资源时导致的资源不同步的问题</p>
<h2 id="7-2-阻塞与非阻塞"><a href="#7-2-阻塞与非阻塞" class="headerlink" title="7.2. 阻塞与非阻塞"></a>7.2. 阻塞与非阻塞</h2><p>阻塞和非阻塞关注的是程序在等待调用结果（消息，返回值）时的状态.</p>
<p>阻塞调用是指调用结果返回之前，当前线程会被挂起。调用线程只有在得到结果之后才会返回。<br>非阻塞调用指在不能立刻得到结果之前，该调用不会阻塞当前线程。</p>
<h2 id="7-3-区别"><a href="#7-3-区别" class="headerlink" title="7.3. 区别"></a>7.3. 区别</h2><p>阻塞代码不继续往下执行，不占用cpu，同步的话代码会继续执行（进入方法里面执行），占用cpu</p>
<h1 id="锁"><a href="#锁" class="headerlink" title="锁"></a>锁</h1><h2 id="Lock和synchronized区别："><a href="#Lock和synchronized区别：" class="headerlink" title="Lock和synchronized区别："></a>Lock和synchronized区别：</h2><ol>
<li>Lock是一个接口，而synchronized是Java中的关键字，synchronized是内置的语言实现；</li>
<li>synchronized在发生异常时，会自动释放线程占有的锁，因此不会导致死锁现象发生；而Lock在发生异常时，如果没有主动通过unLock()去释放锁，则很可能造成死锁现象，因此使用Lock时需要在finally块中释放锁；</li>
<li>Lock可以让等待锁的线程响应中断，而synchronized却不行，使用synchronized时，等待的线程会一直等待下去，不能够响应中断；（I/O和Synchronized都能相应中断，即不需要处理interruptionException异常）</li>
<li>通过Lock可以知道有没有成功获取锁，而synchronized却无法办到。</li>
<li>Lock可以提高多个线程进行读操作的效率。</li>
<li>在性能上来说，如果竞争资源不激烈，两者的性能是差不多的，而当竞争资源非常激烈时（即有大量线程同时竞争），此时Lock的性能要远远优于synchronized。所以说，在具体使用时要根据适当情况选择。</li>
</ol>
<p>1 、在使用synchronized关键字的情形下，假如占有锁的线程由于要等待IO或者其他原因（比如调用sleep方法）被阻塞了，但是又没有释放锁，那么其他线程就只能一直等待，别无他法。这会极大影响程序执行效率。因此，就需要有一种机制可以不让等待的线程一直无期限地等待下去（比如只等待一定的时间 (解决方案：tryLock(long time, TimeUnit unit))或者能够响应中断(解决方案：lockInterruptibly())），这种情况可以通过 Lock 解决。</p>
<p>2、当多个线程读写文件时，读操作和写操作会发生冲突现象，写操作和写操作也会发生冲突现象，但是读操作和读操作不会发生冲突现象。但是如果采用synchronized关键字实现同步的话，就会导致一个问题，即当多个线程都只是进行读操作时，也只有一个线程在可以进行读操作，其他线程只能等待锁的释放而无法进行读操作。因此，需要一种机制来使得当多个线程都只是进行读操作时，线程之间不会发生冲突。同样地，Lock也可以解决这种情况 (解决方案：ReentrantReadWriteLock) 。</p>
<p>3、通过Lock得知线程有没有成功获取到锁 (解决方案：ReentrantLock) ，但这个是synchronized无法办到的。</p>
<p>上面提到的三种情形，我们都可以通过Lock来解决，但 synchronized 关键字却无能为力。事实上，Lock 是 java.util.concurrent.locks包 下的接口，Lock 实现提供了比 synchronized 关键字更广泛的锁操作，它能以更优雅的方式处理线程同步问题。也就是说，Lock提供了比synchronized更多的功能。</p>

    </div>

    
    
    
        

  <div class="followme">
    <p>欢迎关注我的其它发布渠道</p>

    <div class="social-list">

        <div class="social-item">
          <a target="_blank" class="social-link" href="/images/wechat_channel.jpg">
            <span class="icon">
              <i class="fab fa-weixin"></i>
            </span>

            <span class="label">WeChat</span>
          </a>
        </div>
    </div>
  </div>


      <footer class="post-footer">
          
          <div class="post-tags">
              <a href="/" rel="tag"><i class="fa fa-tag"></i> </a>
          </div>

        


        
    <div class="post-nav">
      <div class="post-nav-item">
    <a href="/2018/11/04/tool-2018-11-04-Docker/" rel="prev" title="Docker笔记">
      <i class="fa fa-chevron-left"></i> Docker笔记
    </a></div>
      <div class="post-nav-item">
    <a href="/2018/11/17/algorithm-2018-11-17-strategy/" rel="next" title="策略模式和状态模式">
      策略模式和状态模式 <i class="fa fa-chevron-right"></i>
    </a></div>
    </div>
      </footer>
    
  </article>
  
  
  



          </div>
          

<script>
  window.addEventListener('tabs:register', () => {
    let { activeClass } = CONFIG.comments;
    if (CONFIG.comments.storage) {
      activeClass = localStorage.getItem('comments_active') || activeClass;
    }
    if (activeClass) {
      let activeTab = document.querySelector(`a[href="#comment-${activeClass}"]`);
      if (activeTab) {
        activeTab.click();
      }
    }
  });
  if (CONFIG.comments.storage) {
    window.addEventListener('tabs:click', event => {
      if (!event.target.matches('.tabs-comment .tab-content .tab-pane')) return;
      let commentClass = event.target.classList[1];
      localStorage.setItem('comments_active', commentClass);
    });
  }
</script>

        </div>
          
  
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="header-overlay"></div>
    <div class="sidebar-inner">

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          文章目录
        </li>
        <li class="sidebar-nav-overview">
          站点概览
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
          <div class="post-toc motion-element"><ol class="nav"><li class="nav-item nav-level-1"><a class="nav-link" href="#1-%E8%BF%9B%E7%A8%8B%E5%92%8C%E7%BA%BF%E7%A8%8B"><span class="nav-number">1.</span> <span class="nav-text">1. 进程和线程</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#2-%E5%B9%B6%E8%A1%8C%E5%92%8C%E5%B9%B6%E5%8F%91"><span class="nav-number">2.</span> <span class="nav-text">2. 并行和并发</span></a></li><li class="nav-item nav-level-1"><a class="nav-link" href="#3-%E8%BF%9B%E7%A8%8B%E9%97%B4%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F"><span class="nav-number">3.</span> <span class="nav-text">3. 进程间通信方式</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#3-1-%E7%AE%A1%E9%81%93-pipe"><span class="nav-number">3.1.</span> <span class="nav-text">3.1. 管道( pipe )</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-2-%E6%9C%89%E5%90%8D%E7%AE%A1%E9%81%93-namedpipe"><span class="nav-number">3.2.</span> <span class="nav-text">3.2. 有名管道 (namedpipe)</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-3-%E4%BF%A1%E5%8F%B7%E9%87%8F-semophore"><span class="nav-number">3.3.</span> <span class="nav-text">3.3. 信号量(semophore )</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-4-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97-messagequeue"><span class="nav-number">3.4.</span> <span class="nav-text">3.4. 消息队列( messagequeue )</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-5-%E4%BF%A1%E5%8F%B7-sinal"><span class="nav-number">3.5.</span> <span class="nav-text">3.5. 信号 (sinal )</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-6-%E5%85%B1%E4%BA%AB%E5%86%85%E5%AD%98-shared-memory"><span class="nav-number">3.6.</span> <span class="nav-text">3.6. 共享内存(shared memory )</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#3-7-%E5%A5%97%E6%8E%A5%E5%AD%97-socket"><span class="nav-number">3.7.</span> <span class="nav-text">3.7. 套接字(socket )</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#4-%E7%BA%BF%E7%A8%8B%E9%97%B4%E7%9A%84%E5%90%8C%E6%AD%A5"><span class="nav-number">4.</span> <span class="nav-text">4. 线程间的同步</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#4-1-%E9%94%81%E6%9C%BA%E5%88%B6%EF%BC%9A%E5%8C%85%E6%8B%AC%E4%BA%92%E6%96%A5%E9%94%81%E3%80%81%E8%AF%BB%E5%86%99%E9%94%81%E3%80%81%E6%9D%A1%E4%BB%B6%E5%8F%98%E9%87%8F"><span class="nav-number">4.1.</span> <span class="nav-text">4.1. 锁机制：包括互斥锁、读写锁、条件变量</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-2-%E4%BF%A1%E5%8F%B7%E9%87%8F%E6%9C%BA%E5%88%B6-Semaphore-%EF%BC%9A%E5%8C%85%E6%8B%AC%E6%97%A0%E5%90%8D%E7%BA%BF%E7%A8%8B%E4%BF%A1%E5%8F%B7%E9%87%8F%E5%92%8C%E5%91%BD%E5%90%8D%E7%BA%BF%E7%A8%8B%E4%BF%A1%E5%8F%B7%E9%87%8F"><span class="nav-number">4.2.</span> <span class="nav-text">4.2. 信号量机制(Semaphore)：包括无名线程信号量和命名线程信号量</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-3-%E4%BF%A1%E5%8F%B7%E6%9C%BA%E5%88%B6-Signal-%EF%BC%9A%E7%B1%BB%E4%BC%BC%E8%BF%9B%E7%A8%8B%E9%97%B4%E7%9A%84%E4%BF%A1%E5%8F%B7%E5%A4%84%E7%90%86"><span class="nav-number">4.3.</span> <span class="nav-text">4.3. 信号机制(Signal)：类似进程间的信号处理</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#4-4-%E4%B8%B4%E7%95%8C%E5%8C%BA"><span class="nav-number">4.4.</span> <span class="nav-text">4.4. 临界区</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#5-java%E7%BA%BF%E7%A8%8B%E9%97%B4%E7%9A%84%E9%80%9A%E4%BF%A1%E6%96%B9%E5%BC%8F"><span class="nav-number">5.</span> <span class="nav-text">5. java线程间的通信方式</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#5-1-%E4%BD%BF%E7%94%A8%E5%85%B1%E4%BA%AB%E5%AF%B9%E8%B1%A1"><span class="nav-number">5.1.</span> <span class="nav-text">5.1. 使用共享对象</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#%E5%8C%BA%E5%88%AB"><span class="nav-number">5.1.1.</span> <span class="nav-text">区别</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-2-while%E8%BD%AE%E8%AF%A2%EF%BC%9A%E5%BF%99%E7%AD%89%E7%8A%B6%E6%80%81%EF%BC%8C%E6%B6%88%E8%80%97cpu%E8%B5%84%E6%BA%90%E3%80%82%E5%8F%AF%E4%BD%BF%E7%94%A8wait%E9%98%BB%E5%A1%9E%E6%9B%BF%E4%BB%A3"><span class="nav-number">5.2.</span> <span class="nav-text">5.2. while轮询：忙等状态，消耗cpu资源。可使用wait阻塞替代</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-3-%E6%8E%A5%E5%8F%A3%E5%9B%9E%E8%B0%83"><span class="nav-number">5.3.</span> <span class="nav-text">5.3. 接口回调</span></a><ol class="nav-child"><li class="nav-item nav-level-3"><a class="nav-link" href="#java%E6%8F%90%E4%BE%9B%E7%9A%84Callable%EF%BC%8CFuture%EF%BC%8CExecutorService%E3%80%82"><span class="nav-number">5.3.1.</span> <span class="nav-text">java提供的Callable，Future，ExecutorService。</span></a></li></ol></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-4-IO%E7%AE%A1%E9%81%93%E6%B5%81%EF%BC%9APipedInputStream%EF%BC%8CPipedOutputStream"><span class="nav-number">5.4.</span> <span class="nav-text">5.4. IO管道流：PipedInputStream，PipedOutputStream</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-5-socket%E5%A5%97%E6%8E%A5%E5%AD%97"><span class="nav-number">5.5.</span> <span class="nav-text">5.5. socket套接字</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-6-%E6%B6%88%E6%81%AF%E9%98%9F%E5%88%97"><span class="nav-number">5.6.</span> <span class="nav-text">5.6. 消息队列</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#5-7-wait-%EF%BC%8Cnotify-%EF%BC%8CnotifyAll-%E9%98%BB%E5%A1%9E%E5%92%8C%E5%94%A4%E9%86%92%E7%BA%BF%E7%A8%8B"><span class="nav-number">5.7.</span> <span class="nav-text">5.7. wait()，notify()，notifyAll()阻塞和唤醒线程</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#6-%E7%BA%BF%E7%A8%8B%E7%8A%B6%E6%80%81"><span class="nav-number">6.</span> <span class="nav-text">6. 线程状态</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#6-1-%E7%BA%BF%E7%A8%8B%E5%85%B1%E5%8C%85%E6%8B%AC%E4%BB%A5%E4%B8%8B5%E7%A7%8D%E7%8A%B6%E6%80%81%E3%80%82"><span class="nav-number">6.1.</span> <span class="nav-text">6.1. 线程共包括以下5种状态。</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#6-2-yield%EF%BC%8Csleep%EF%BC%8Cjoin%E9%83%BD%E6%98%AFThread%E7%9A%84%E6%96%B9%E6%B3%95"><span class="nav-number">6.2.</span> <span class="nav-text">6.2. yield，sleep，join都是Thread的方法</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#7-%E5%90%8C%E6%AD%A5%E5%92%8C%E5%BC%82%E6%AD%A5%E3%80%81%E9%98%BB%E5%A1%9E%E4%B8%8E%E9%9D%9E%E9%98%BB%E5%A1%9E"><span class="nav-number">7.</span> <span class="nav-text">7. 同步和异步、阻塞与非阻塞</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#7-1-%E5%90%8C%E6%AD%A5%E4%B8%8E%E5%BC%82%E6%AD%A5"><span class="nav-number">7.1.</span> <span class="nav-text">7.1. 同步与异步</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-2-%E9%98%BB%E5%A1%9E%E4%B8%8E%E9%9D%9E%E9%98%BB%E5%A1%9E"><span class="nav-number">7.2.</span> <span class="nav-text">7.2. 阻塞与非阻塞</span></a></li><li class="nav-item nav-level-2"><a class="nav-link" href="#7-3-%E5%8C%BA%E5%88%AB"><span class="nav-number">7.3.</span> <span class="nav-text">7.3. 区别</span></a></li></ol></li><li class="nav-item nav-level-1"><a class="nav-link" href="#%E9%94%81"><span class="nav-number">8.</span> <span class="nav-text">锁</span></a><ol class="nav-child"><li class="nav-item nav-level-2"><a class="nav-link" href="#Lock%E5%92%8Csynchronized%E5%8C%BA%E5%88%AB%EF%BC%9A"><span class="nav-number">8.1.</span> <span class="nav-text">Lock和synchronized区别：</span></a></li></ol></li></ol></div>
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
    <img class="site-author-image" itemprop="image" alt="丘山月夜"
      src="/images/avatar.png">
  <p class="site-author-name" itemprop="name">丘山月夜</p>
  <div class="site-description" itemprop="description">君は空を見てるか,<br>風の音を聞いてるか</div>
</div>
<div class="site-state-wrap motion-element">
  <nav class="site-state">
      <div class="site-state-item site-state-posts">
          <a href="/archives/">
        
          <span class="site-state-item-count">60</span>
          <span class="site-state-item-name">日志</span>
        </a>
      </div>
      <div class="site-state-item site-state-categories">
            <a href="/categories/">
          
        <span class="site-state-item-count">14</span>
        <span class="site-state-item-name">分类</span></a>
      </div>
      <div class="site-state-item site-state-tags">
            <a href="/tags/">
          
        <span class="site-state-item-count">21</span>
        <span class="site-state-item-name">标签</span></a>
      </div>
  </nav>
</div>



      </div>

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>


      </div>
    </main>

    <footer class="footer">
      <div class="footer-inner">
        

        

<div class="copyright">
  
  &copy; 
  <span itemprop="copyrightYear">2021</span>
  <span class="with-love">
    <i class="fa fa-heart"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">丘山月夜</span>
</div>
  <div class="powered-by">由 <a href="https://hexo.io/" class="theme-link" rel="noopener" target="_blank">Hexo</a> & <a href="https://mist.theme-next.org/" class="theme-link" rel="noopener" target="_blank">NexT.Mist</a> 强力驱动
  </div>

        








      </div>
    </footer>
  </div>

  
  <script src="/lib/anime.min.js"></script>
  <script src="/lib/velocity/velocity.min.js"></script>
  <script src="/lib/velocity/velocity.ui.min.js"></script>

<script src="/js/utils.js"></script>

<script src="/js/motion.js"></script>


<script src="/js/schemes/muse.js"></script>


<script src="/js/next-boot.js"></script>




  















  

  

</body>
</html>
